package com.second.service.impl;

import com.second.consts.PersonalConst;
import com.second.consts.OrderStatus;
import com.second.consts.TypeConst;
import com.second.mapper.*;
import com.second.model.dto.personal.PersonalOrder;
import com.second.model.dto.personal.Recent;
import com.second.model.dto.recommend.FShopRecommendVo;
import com.second.model.dto.recommend.RecommendVo;
import com.second.model.pojo.*;
import com.second.service.IFUserService;
import com.second.util.UserCF;
import com.second.util.createCsvUtil;
import org.apache.mahout.cf.taste.common.TasteException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class FUserServiceImpl implements IFUserService {
    final static String UserCFPath = "src/data/UserCF.csv";

    @Autowired
    private FUserMapper userMapper;

    @Autowired
    private FRecommendVoMapper recommendVoMapper;

    @Autowired
    private FShopMapper shopMapper;

    @Autowired
    private FCollectionMapper collectionMapper;

    @Autowired
    private FShopPictureMapper shopPictureMapper;

    @Autowired
    private FCommentMapper commentMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private FMessageMapper messageMapper;

    @Autowired
    private FShopDao shopDao;

    @Autowired
    private IFOrdMapper ordMapper;

    @Autowired
    private FGoodsMapper goodsMapper;

    /**
     * 根据电话号码查询登录是否成功
     * @param TelNumber
     * @return
     */
    @Override
    public FUser login(String TelNumber) {
        FUser user = userMapper.findByTelNumber(TelNumber);
        if (null!=user){
            List<FRecommendvo> list = recommendVoMapper.findAll();
            List<RecommendVo> lists = new ArrayList<>();
            for (FRecommendvo vo : list) {
                RecommendVo v = new RecommendVo();
                v.setUserId(vo.getUserId());
                v.setShopId(vo.getShopId());
                v.setScore(vo.getScore());
                lists.add(v);
            }
            createCsvUtil.writeCSV(lists,UserCFPath);
        }

        return user;
    }

    @Override
    public int register(FUser user) {
        FUser fUser = userMapper.findByTelNumber(user.getTelNumber());
        if (null!=fUser){
            return 0;
        }else {
            userMapper.save(user);
            return 1;
        }
    }

    /**
     * 根据用户id查询推荐列表
     * @param userId 用户id
     * @return
     * @throws IOException
     * @throws TasteException
     */
    @Override
    public List<FShop> recommend(Integer userId) throws IOException, TasteException {
        //记录是否包含收藏的shop
        int count = 0;
        List<FShop> list = new ArrayList<>();
        //根据推荐出来的列表中的shopId去查询对应的FShop对象添加到集合中
        //还要对比用户收藏的商店列表如果收藏了就不添加
        List<FCollection> collections = collectionMapper.findAllByUserIdAndStatus(userId, PersonalConst.Collected_Status);
        List<RecommendVo> RVoList = UserCF.userRecommend(userId);
        if (null != RVoList){
            for (RecommendVo v : RVoList) {
                //根据shopId查询到单个FShop对象
                FShop shop = shopMapper.getById(v.getShopId());
                //遍历该用户的收藏表
                for (FCollection c : collections) {
                    if (c.getShopId()==v.getShopId()){
                        count = 1;
                        break;
                    }
                }
                if (count == 1){
                    count = 0;
                    continue;
                }else {
                    list.add(shop);
                }
            }
        }

        List<FShop> SupList = shopMapper.findAllByScoreDesc();
        //如果数量不足5个继续补充评分最高的
        boolean flag = false;
        if (list.size()<5){
            for (FShop sup : SupList) {
                for (FShop rec : list) {
                    if (rec.getId()==sup.getId()){
                        flag = true;
                        break;
                    }
                }
                for (FCollection c : collections) {
                    if (c.getShopId()==sup.getId()){
                        flag = true;
                        break;
                    }
                }
                if (flag == false){
                    list.add(sup);
                }else if (flag == true){
                    flag = false;
                    continue;
                }
                if (list.size()>=5)
                    return list;
            }
        }
        return list;
    }
    /**
     * 根据用户id查询推荐列表返回午餐推荐对象
     * @param userId 用户id
     * @return
     * @throws IOException
     * @throws TasteException
     */
    @Override
    public List<FShop> recommendLunch(Integer userId) throws IOException, TasteException {
        //记录是否包含收藏的shop
        int count = 0;
        List<FShop> list = new ArrayList<>();
        //根据推荐出来的列表中的shopId去查询对应的FShop对象添加到集合中
        //还要对比用户收藏的商店列表如果收藏了就不添加
        List<FCollection> collections = collectionMapper.findAllByUserIdAndStatus(userId, PersonalConst.Collected_Status);
        List<RecommendVo> RVoList = UserCF.userRecommend(userId);
        if (null!=RVoList){
            for (RecommendVo v : RVoList) {
                //根据shopId查询到单个FShop对象
                FShop shop = shopMapper.getById(v.getShopId());
                //遍历该用户的收藏表
                for (FCollection c : collections) {
                    if (c.getShopId()==v.getShopId()){
                        count = 1;
                        break;
                    }
                }
                if (count == 1){
                    count = 0;
                    continue;
                }else {
                    //当此店铺为午餐的店铺才添加
                    if (shop.getShopStatus()==TypeConst.Lunch){
                        list.add(shop);
                    }else continue;
                }
            }
        }

        List<FShop> SupList = shopMapper.findAllByStatusAndScoreDesc(TypeConst.Lunch);
        //如果数量不足5个继续补充评分最高的
        boolean flag = false;
        if (list.size()<4){
            for (FShop sup : SupList) {
                for (FShop rec : list) {
                    if (rec.getId()==sup.getId()){
                        flag = true;
                        break;
                    }
                }
                for (FCollection c : collections) {
                    if (c.getShopId()==sup.getId()){
                        flag = true;
                        break;
                    }
                }
                if (flag == false){
                    list.add(sup);
                }else if (flag == true){
                    flag = false;
                    continue;
                }
                if (list.size()>=4)
                    break;
            }
        }
        return list;
    }

    /**
     * 根据用户id查询推荐列表返回晚餐推荐对象
     * @param userId 用户id
     * @return
     * @throws IOException
     * @throws TasteException
     */
    @Override
    public List<FShop> recommendDinner(Integer userId) throws IOException, TasteException {
        //记录是否包含收藏的shop
        int count = 0;
        List<FShop> list = new ArrayList<>();
        //根据推荐出来的列表中的shopId去查询对应的FShop对象添加到集合中
        //还要对比用户收藏的商店列表
        List<FCollection> collections = collectionMapper.findAllByUserIdAndStatus(userId, PersonalConst.Collected_Status);
        List<RecommendVo> RVoList = UserCF.userRecommend(userId);
        if (null!=RVoList){
            for (RecommendVo v : RVoList) {
                //根据shopId查询到单个FShop对象
                FShop shop = shopMapper.getById(v.getShopId());
                //遍历该用户的收藏表
                for (FCollection c : collections) {
                    //如果收藏了就不添加
                    if (c.getShopId()==v.getShopId()){
                        count = 1;
                        break;
                    }
                }
                if (count == 1){
                    count = 0;
                    continue;
                }else {
                    //当此店铺为午餐的店铺才添加
                    if (shop.getShopStatus()==TypeConst.Dinner){
                        list.add(shop);
                    }else continue;
                }
            }
        }

        List<FShop> SupList = shopMapper.findAllByStatusAndScoreDesc(TypeConst.Dinner);
        //如果数量不足5个继续补充评分最高的
        boolean flag = false;
        if (list.size()<4){
            for (FShop sup : SupList) {
                for (FShop rec : list) {
                    if (rec.getId()==sup.getId()){
                        flag = true;
                        break;
                    }
                }
                for (FCollection c : collections) {
                    if (c.getShopId()==sup.getId()){
                        flag = true;
                        break;
                    }
                }
                if (flag == false){
                    list.add(sup);
                }else if (flag == true){
                    flag = false;
                    continue;
                }
                if (list.size()>=4)
                    return list;
            }
        }
        return list;
    }

    /**
     * 登录用户后页面需要的推荐店铺集合
     * @param userId
     * @return
     */
    @Override
    public List<FShopRecommendVo> recommendList(Integer userId) throws IOException, TasteException {
        if (null!=userId){
            List<FShop> shops = recommend(userId);
            List<FShopRecommendVo> list = new ArrayList<>();
            for (FShop shop : shops) {
                FCollection fCollection = collectionMapper.findByUserIdAndShopId(userId, shop.getId());
                FShopRecommendVo v = new FShopRecommendVo();
                v.setShopId(shop.getId());
                v.setShopName(shop.getShopName());
                v.setUserId(userId);
                String picture = shopPictureMapper.findByShopId(shop.getId()).getUrl1();
                v.setShopPicture(picture);
                v.setShopScore(shop.getShopScore());
                v.setCommentCount(commentMapper.countByShopId(shop.getId()));
                v.setProvince(shop.getProvince());
                v.setCity(shop.getCity());
                if (null == fCollection) {
                    v.setCollectionStatus(PersonalConst.Not_Collected_Status);
                } else {
                    v.setCollectionStatus(fCollection.getStatus());
                }
                list.add(v);
            }
            return list;
        }else return recommend();
    }

    /**
     * 登录用户后页面需要的午餐推荐店铺集合
     * @param userId
     * @return
     * @throws IOException
     * @throws TasteException
     */
    @Override
    public List<FShopRecommendVo> recommendLunchList(Integer userId) throws IOException, TasteException {
        if (null!=userId){
            List<FShop> shops = recommendLunch(userId);
            List<FShopRecommendVo> list = new ArrayList<>();
            for (FShop shop : shops) {
                FCollection fCollection = collectionMapper.findByUserIdAndShopId(userId, shop.getId());
                FShopRecommendVo v = new FShopRecommendVo();
                v.setShopId(shop.getId());
                v.setShopName(shop.getShopName());
                v.setUserId(userId);
                String picture = shopPictureMapper.findByShopId(shop.getId()).getUrl1();
                v.setShopPicture(picture);
                v.setShopScore(shop.getShopScore());
                v.setCommentCount(commentMapper.countByShopId(shop.getId()));
                v.setProvince(shop.getProvince());
                v.setCity(shop.getCity());
                if (null == fCollection) {
                    v.setCollectionStatus(PersonalConst.Not_Collected_Status);
                } else {
                    v.setCollectionStatus(fCollection.getStatus());
                }
                list.add(v);
            }
            return list;
        }else return recommendLunch();
    }

    /**
     * 登录用户后页面需要的晚餐推荐店铺集合
     * @param userId
     * @return
     * @throws IOException
     * @throws TasteException
     */
    @Override
    public List<FShopRecommendVo> recommendDinnerList(Integer userId) throws IOException, TasteException {
        if (null!=userId){
            List<FShop> shops = recommendDinner(userId);
            List<FShopRecommendVo> list = new ArrayList<>();
            for (FShop shop : shops) {
                FCollection fCollection = collectionMapper.findByUserIdAndShopId(userId, shop.getId());
                FShopRecommendVo v = new FShopRecommendVo();
                v.setShopId(shop.getId());
                v.setShopName(shop.getShopName());
                v.setUserId(userId);
                String picture = shopPictureMapper.findByShopId(shop.getId()).getUrl1();
                v.setShopPicture(picture);
                v.setShopScore(shop.getShopScore());
                v.setCommentCount(commentMapper.countByShopId(shop.getId()));
                v.setProvince(shop.getProvince());
                v.setCity(shop.getCity());
                if (null == fCollection) {
                    v.setCollectionStatus(PersonalConst.Not_Collected_Status);
                } else {
                    v.setCollectionStatus(fCollection.getStatus());
                }
                list.add(v);
            }
            return list;
        }else return recommendDinner();
    }

    /**
     * 用户未登录的时候页面需要的推荐店铺集合
     * @return
     */
    @Override
    public List<FShopRecommendVo> recommend() {
        List<FShop> SupList = shopMapper.findAllByScoreDesc();
        List<FShop> shops = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            shops.add(SupList.get(i));
        }
        List<FShopRecommendVo> list = new ArrayList<>();
        for (FShop shop : shops) {
            FShopRecommendVo v = new FShopRecommendVo();
            v.setShopId(shop.getId());
            v.setShopName(shop.getShopName());
            String picture = shopPictureMapper.findByShopId(shop.getId()).getUrl1();
            v.setShopPicture(picture);
            v.setShopScore(shop.getShopScore());
            v.setCommentCount(commentMapper.countByShopId(shop.getId()));
            v.setProvince(shop.getProvince());
            v.setCity(shop.getCity());
            list.add(v);
        }
        return list;
    }

    /**
     * 用户未登录的时候页面需要的午餐推荐店铺集合
     * @return
     */
    @Override
    public List<FShopRecommendVo> recommendLunch() {
        List<FShop> SupList = shopMapper.findAllByStatusAndScoreDesc(TypeConst.Lunch);
        List<FShop> shops = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            shops.add(SupList.get(i));
        }
        List<FShopRecommendVo> list = new ArrayList<>();
        for (FShop shop : shops) {
            FShopRecommendVo v = new FShopRecommendVo();
            v.setShopId(shop.getId());
            v.setShopName(shop.getShopName());
            String picture = shopPictureMapper.findByShopId(shop.getId()).getUrl1();
            v.setShopPicture(picture);
            v.setShopScore(shop.getShopScore());
            v.setCommentCount(commentMapper.countByShopId(shop.getId()));
            v.setProvince(shop.getProvince());
            v.setCity(shop.getCity());
            list.add(v);
        }
        return list;
    }
    /**
     * 用户未登录的时候页面需要的晚餐推荐店铺集合
     * @return
     */
    @Override
    public List<FShopRecommendVo> recommendDinner() {
        List<FShop> SupList = shopMapper.findAllByStatusAndScoreDesc(TypeConst.Dinner);
        List<FShop> shops = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            shops.add(SupList.get(i));
        }
        List<FShopRecommendVo> list = new ArrayList<>();
        for (FShop shop : shops) {
            FShopRecommendVo v = new FShopRecommendVo();
            v.setShopId(shop.getId());
            v.setShopName(shop.getShopName());
            String picture = shopPictureMapper.findByShopId(shop.getId()).getUrl1();
            v.setShopPicture(picture);
            v.setShopScore(shop.getShopScore());
            v.setCommentCount(commentMapper.countByShopId(shop.getId()));
            v.setProvince(shop.getProvince());
            v.setCity(shop.getCity());
            list.add(v);
        }
        return list;
    }

    /**
     * 修改个人信息
     * @param user
     * @return
     */
    @Override
    public FUser changeInfo(FUser user) {
        FUser fUser = userMapper.findByTelNumber(user.getTelNumber());
        fUser.setUsername(user.getUsername());
        String fileUrl = (String) redisTemplate.opsForValue().get("headPicture");
        fUser.setHeadPicture("https://foodreviews.oss-cn-hangzhou.aliyuncs.com/"+fileUrl);
        fUser.setProvince(user.getProvince());
        fUser.setCity(user.getCity());
        fUser.setArea(user.getArea());
        fUser.setLeftConsum(user.getLeftConsum());
        fUser.setRightConsum(user.getRightConsum());
        fUser.setFlavorId(user.getFlavorId());
        fUser.setSignature(user.getSignature());
        userMapper.save(fUser);
        return fUser;
    }
    /**
     * 根据当前用户查询最近的三个回复消息显示到个人中心首页
     * @param userId
     * @return
     */
    @Override
    public List<FMessage> getThreeMessage(Integer userId) {
        List<FMessage> allList = messageMapper.findAllByUserIdOrderByReplyTimeDesc(userId);
        List<FMessage> list = new ArrayList<>();
        if (allList.size()>3){
            for (int i = 0; i < 3; i++) {
                list.add(allList.get(i));
            }
            return list;
        }else return allList;

    }

    /**
     * 根据当前用户查询最近的四个订单显示到个人中心首页
     * @param userId
     * @return
     */
    @Override
    public List<PersonalOrder> getFourOrders(Integer userId) {
        List<FOrd> ordList = ordMapper.findAllByUserIdAndOrdStateOrderByOrdCreateDateDesc(userId, OrderStatus.Order_Used);
        List<PersonalOrder> list = new ArrayList<>();
        if (ordList.size()>=4){
            for (int i = 0; i < 4; i++) {
                PersonalOrder po = new PersonalOrder();
                po.setShopName(shopDao.getById(ordList.get(i).getShopId()).getShopName());
                po.setShopId(ordList.get(i).getShopId());
                po.setStatus(ordList.get(i).getOperation());
                po.setGoodName(goodsMapper.getById(ordList.get(i).getGoodsId()).getGoodsName());
                po.setPicture(goodsMapper.getById(ordList.get(i).getGoodsId()).getGoodsPicture());
                po.setShopScore(shopDao.getById(ordList.get(i).getShopId()).getShopScore());
                po.setUserTime(ordList.get(i).getOrdCreateDate());
                po.setOrderId(ordList.get(i).getId());
                list.add(po);
            }
            return list;
        }else {
            for (FOrd fOrd : ordList) {
                PersonalOrder po = new PersonalOrder();
                po.setShopId(fOrd.getShopId());
                po.setStatus(fOrd.getOperation());
                po.setGoodName(goodsMapper.getById(fOrd.getGoodsId()).getGoodsName());
                po.setPicture(goodsMapper.getById(fOrd.getGoodsId()).getGoodsPicture());
                po.setShopScore(shopDao.getById(fOrd.getShopId()).getShopScore());
                po.setUserTime(fOrd.getOrdCreateDate());
                po.setOrderId(fOrd.getId());
                list.add(po);
            }
            return list;
        }

    }

    /**
     * 根据当前用户查询最近的三个评论显示到个人中心首页
     * @param userId
     * @return
     */
    @Override
    public List<Recent> findThreeComments(Integer userId) {
        List<Recent> list = new ArrayList<>();
        List<FComment> allList = commentMapper.findAllByUserIdOrderByCommentTimeDesc(userId);
        if (allList.size()>3){
            for (int i = 0; i < 3; i++) {
                Recent r = new Recent();
                String shopName = shopDao.getById(allList.get(i).getShopId()).getShopName();
                r.setShopName(shopName);
                r.setAddTime(allList.get(i).getCommentTime());
                list.add(r);
            }
            return list;
        }else {
            for (FComment c : allList) {
                Recent r = new Recent();
                String shopName = shopDao.getById(c.getShopId()).getShopName();
                r.setShopName(shopName);
                r.setAddTime(c.getCommentTime());
                list.add(r);
            }
            return list;
        }
    }
}
